package xyz.wadewhy.basicstest.designPatterns.BuilderPattern;

/**
 * 创建我们的抽象建造者类
 */
abstract class ProductBuilder {
    /**
     * 构建商品
     */
    abstract void buildProduct();

    /**
     * 获得商品
     *
     * @return ProductBase
     */
    abstract ProductBase getProduct();
}

class NormalProductBuilder extends ProductBuilder {
    private static final ProductBase product = new NormalProduct();

    @Override
    void buildProduct() {
        product.getName(ProductTypeEnum.NORMAL);
        product.couponExpiration(30L);
        product.urlLock();
    }

    @Override
    ProductBase getProduct() {
        return product;
    }
    //可以衍生这个类型的业务场景，解偶
}

class VipProductBuilder extends ProductBuilder {
    private static final ProductBase product = new VipProduct();

    @Override
    void buildProduct() {
        product.getName(ProductTypeEnum.VIP);
        product.couponExpiration(100000000000000000L);
        product.urlLock();
    }

    @Override
    ProductBase getProduct() {
        return product;
    }
    /**
     * 可以衍生这个类型的业务场景，解偶
     */
    public void vipBusiness(){
        System.err.println("vip商品自己的业务场景");
    }
}

/**
 * 创建具体建造者类
 * 防腐层
 */
class ConcreteProductBuilder {
    public ProductBuilder getBuilder(int code) {
        if (code == ProductTypeEnum.NORMAL.getCode()) {
            return new NormalProductBuilder();
        } else if (code == ProductTypeEnum.VIP.getCode()) {
            return new VipProductBuilder();
        } else {
            //业务异常
            throw new IllegalArgumentException("未知类型");
        }
    }
}

/**
 * 指导创建对象
 */
class ProductDirector {
    public ProductBase getDirectorBuilder(int code) {
        ProductBuilder builder = new ConcreteProductBuilder().getBuilder(code);
        builder.buildProduct();
        return builder.getProduct();
    }
}

class TestDemo {
    public static void main(String[] args) {
        ProductDirector director = new ProductDirector();
        director.getDirectorBuilder(ProductTypeEnum.NORMAL.getCode());
        VipProduct vip = (VipProduct) director.getDirectorBuilder(ProductTypeEnum.VIP.getCode());
        vip.vipBusiness();
        director.getDirectorBuilder(3);
    }
}
